﻿#include "productservice.h"
#include <QMessageBox>
#include "user.h"
#include <QJsonObject>
#include "dbhelper.h"
#include <QFileDialog>
#include <QMessageBox>
#include "mymessagebox.h"
#include "tools.h"

ProductService::ProductService(QObject *parent) : QObject(parent)
{

}

void ProductService::addProduct(
        QWidget *widget,
        QPushButton *button,
        QString type,
        QString name,
        QString unit,
        QString productNum,
        QString upperLimit,
        QString lowerLimit,
        QString brand,
        QString originPlace,
        QString specifications,
        QString barCode,
        QString remark,
        QString guidePrice1,
        QString guidePrice2,
        QString primaryDirectory,
        QString secondaryDirectory)
{
    QString companyId = User::getCompanyId();

    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::information(widget, "信息", message);
        emit this->addProductSuccess();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::warning(widget, "警告", message);
    });

    button->setEnabled(false);
    manager->addProduct(
                companyId,
                type,
                name,
                unit,productNum,
                upperLimit,
                lowerLimit,
                brand,
                originPlace,
                specifications,
                barCode,
                remark,
                guidePrice1,
                guidePrice2,
                primaryDirectory,
                secondaryDirectory);
}

void ProductService::updateProduct(
        QWidget *widget,
        QString productId,
        QString type,
        QString name,
        QString unit,
        QString productNum,
        QString upperLimit,
        QString lowerLimit,
        QString brand,
        QString originPlace,
        QString specifications,
        QString barCode,
        QString remark,
        QString guidePrice1,
        QString guidePrice2,
        QString primaryDirectory,
        QString secondaryDirectory)
{
    QString companyId = User::getCompanyId();

    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        QMessageBox::information(widget, "信息", message);
        widget->close();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->updateProduct(
                companyId,
                productId,
                type,
                name,
                unit,productNum,
                upperLimit,
                lowerLimit,
                brand,
                originPlace,
                specifications,
                barCode,
                remark,
                guidePrice1,
                guidePrice2,
                primaryDirectory,
                secondaryDirectory);
}

/**
 * 刷新商品，并同步到本地
 * @brief updateProducts
 * @param widget
 * @param productIds
 */
void ProductService::refreshProducts(
        QWidget *widget,
        QString productIds){
    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message)
        QJsonArray productArr = data.value("products").toArray();
        DbHelper db;
        for(QJsonValue productObj:productArr){
            Product *product = new Product();
            product->loadFromJsonObject(productObj.toObject());
            db.updateProduct(product);
        }
    });

    manager->refreshProducts(User::getCompanyId(), productIds);
}

void ProductService::updateProductData(QWidget *widget, ProductTableView *tableView)
{
    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message)
        QJsonArray productArr = data.value("products").toArray();
        DbHelper db;
        db.clearProduct();
        tableView->clear();
        QList<Product*> products;
        for(QJsonValue productobj:productArr){
            Product *product = new Product();
            product->loadFromJsonObject(productobj.toObject());
            db.insertProduct(*product);
            products.append(product);
        }
        tableView->insertProduct(products);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->getProductsByCompanyId(User::getCompanyId());
}

void ProductService::queryProducts(
        ProductTableView *tableView,
        ProductTreeView *treeView,
        int limitIndex,
        QString overallQuery,
        QString typeQuery,
        QString nameQuery)
{
    QString primaryDirectory = treeView->selectedPrimaryDirectory();
    QString secondaryDirectory = treeView->selectedSecondaryDirectory();
    tableView->queryProduct(
                limitIndex,
                overallQuery,
                typeQuery,
                nameQuery,
                primaryDirectory,
                secondaryDirectory);
}

void ProductService::uploadProduct(
        QWidget *widget,
        QList<Product*> products){
    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        Q_UNUSED(message);
        emit this->uploadProductsSuccess();
    });

    manager->uploadProduct(
                Company::getCompanyId(),
                products);
}

void ProductService::uploadProductFinished(QWidget *widget, double totalMoney){
    manager = new ProductNetworkAccessManager();



    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        Q_UNUSED(message);
        widget->close();
    });

    manager->uploadProductFinished(User::getUsername(), totalMoney);
}

Product* ProductService::checkData(int index, QList<QVariant> dataItem)
{

    Product *product = new Product();

    product->type = dataItem[0].toString();
    product->name = dataItem[1].toString();
    product->unit = dataItem[2].toString();
    product->productNum = dataItem[3].toString();
    product->upperLimit = dataItem[4].toInt();
    product->lowerLimit = dataItem[5].toInt();
    product->count = dataItem[6].toInt();
    product->inPrice = dataItem[7].toDouble();
    product->brand = dataItem[8].toString();
    product->originPlace = dataItem[9].toString();
    product->specifications = dataItem[10].toString();
    product->barCode = dataItem[11].toString();
    product->remark = dataItem[12].toString();
    product->guidePrice1 = dataItem[13].toDouble();
    product->guidePrice2 = dataItem[14].toDouble();
    product->primaryDirectory = dataItem[15].toString();
    product->secondaryDirectory = dataItem[16].toString();

    if(product->type.isEmpty() || product->name.isEmpty()){
        MyMessageBox::warning("警告", QString("第%1条数据错误，错误提示：商品型号和商品名称不能为空！").
                           arg(index));
        return nullptr;
    }

    if(product->lowerLimit<0 || product->upperLimit<product->lowerLimit){
        MyMessageBox::warning("警告", QString("第%1条数据错误，错误提示：上限(%2)>=下限(%3)>=0").
                           arg(index).
                           arg(product->upperLimit).
                           arg(product->lowerLimit));
        return nullptr;
    }

    if(product->guidePrice1 <0 || product->guidePrice2<0){
        MyMessageBox::warning("警告", QString("第%1条数据错误，错误提示：指导价格1(%2),指导价格2(%3)>=0").
                           arg(index).
                           arg(product->guidePrice1).
                           arg(product->guidePrice2));
        return nullptr;
    }

    return product;
}

QList<Product*> ProductService::checkData(QList<QList<QVariant>> data){
    QList<Product*> products;

    for(int i=1;i<data.size();i++){
        Product *product = checkData(i, data.at(i));
        if(product == nullptr){
            break;
        }
        products.append(product);
    }

    return products;
}

bool ProductService::checkDataHeader(QList<QVariant> header){
    QStringList correctHeader={
        "商品型号",
        "商品名称",
        "单位",
        "货号",
        "上限",
        "下限",
        "库存数量",
        "净价",
        "商品品牌",
        "商品产地",
        "规格",
        "条形码",
        "备注",
        "指导价格1",
        "指导价格2",
        "一级类别",
        "二级类别"
    };

    if(header.size() != correctHeader.size()){
        MyMessageBox::warning("警告", QString("表头项数为%1，输入表头项长度为%1！").arg(correctHeader.size()).arg(header.size()));
        return false;
    }

    int index = -1;
    for(int i=0; i<header.size(); i++)
    {
        if(header[i] != correctHeader[i]){
            index = i;
            break;
        }
    }

    if(index != -1){
        MyMessageBox::warning("警告", QString("表头项%1错误，检测到的表头项为：%2 正确表头项为：%3")
                           .arg(index+1).
                           arg(header[index].toString()).
                           arg(correctHeader[index]));
        return false;
    }

    return true;
}

void ProductService::addFormula(QWidget *widget, Product *combineProduct, int combineCount, QList<Product*> splitProducts){
    if(combineProduct == nullptr){
        QMessageBox::warning(widget, "警告", "未选择总成商品！");
        return;
    }

    if(combineCount<1){
        QMessageBox::warning(widget, "警告", "总成商品数量最小为1");
        return;
    }
    combineProduct->count = combineCount;

    if(splitProducts.size() == 0){
        QMessageBox::warning(widget, "警告", "未选择拆分商品！");
        return;
    }

    Formula formula;
    formula.setCombineProduct(combineProduct);
    formula.setSplitProducts(splitProducts);

    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        QMessageBox::information(widget, "信息", message);
        widget->close();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->addFormula(Company::getCompanyId(), *formula.formulaBase);
}

void ProductService::deleteFormula(QWidget *widget, QString combineId){
    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        QMessageBox::information(widget, "信息", message);
        emit this->deleteFormulaSuccess();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->deleteFormula(User::getCompanyId(), combineId);
}

void ProductService::updateFormulaData(QWidget *widget){
    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QJsonArray productArr = data.value("formulas").toArray();
        DbHelper db;
        db.clearFormula();
        QList<Formula*> formulas;
        for(QJsonValue formulaObj:productArr){
            FormulaBase *formulaBase = new FormulaBase();
            formulaBase->loadFromJsonObject(formulaObj.toObject());
            Formula *formula = new Formula(formulaBase);
            db.insertFormula(*formulaBase);
            formulas.append(formula);
        }

        emit this->updateFormulaSuccess(formulas);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    manager->getFormulasByCompanyId(Company::getCompanyId());
}

void ProductService::combineProduct(QWidget *widget, QPushButton *button, Formula *formula, int combineCount){
    manager = new ProductNetworkAccessManager();

    QString productIds = formula->formulaBase->combineId;
    productIds.append("#");
    productIds.append(formula->formulaBase->splitIds);

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::information(widget, "信息", message);
        widget->close();
        this->refreshProducts(widget, productIds);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::warning(widget, "警告", message);
    });

    button->setEnabled(false);
    manager->combineProduct(Company::getCompanyId(), formula->formulaBase->combineId, combineCount);
}

void ProductService::splitProduct(QWidget *widget, QPushButton *button, Formula *formula, int splitCount, QString splitInPrices){
    manager = new ProductNetworkAccessManager();

    QString productIds = formula->formulaBase->combineId;
    productIds.append("#");
    productIds.append(formula->formulaBase->splitIds);

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::information(widget, "信息", message);
        widget->close();
        this->refreshProducts(widget, productIds);
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::warning(widget, "警告", message);
    });

    button->setEnabled(false);
    manager->splitProduct(
                User::getUsername(),
                Company::getCompanyId(),
                formula->formulaBase->combineId,
                splitCount,
                splitInPrices);
}

void ProductService::countProduct(QWidget *widget, QPushButton *button, QList<Product*> products){
    for(Product *product:products){
        if(product->countNum-product->sanbao<0){
            QMessageBox::warning(widget, "警告", "商品["+product->name+"]盘点数量不合法！");
            return;
        }
    }

    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::information(widget, "信息", message);
        emit this->countProductSuccess();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::warning(widget, "警告", message);
    });

    button->setEnabled(false);
    manager->countProducts(User::getUsername(), Company::getCompanyId(), products);
}

void ProductService::sanbaoMove(QWidget *widget, QPushButton *button, QList<Product*> products, Product::SanBaoMoveType moveType){
    QString moveCount;
    QList<Product*> checkedProducts;
    for(Product *product:products){
        if(product->sanbaoMoveCount>0){
            moveCount.append(QString("%1#").arg(product->sanbaoMoveCount));
            checkedProducts.append(product);
        }
    }

    if(checkedProducts.size() == 0){
        QMessageBox::warning(widget, "警告", "无符号条件商品！");
        return;
    }

    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::information(widget, "信息", message);
        this->updateProductData();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        button->setEnabled(true);
        QMessageBox::warning(widget, "警告", message);
    });

    button->setEnabled(false);
    manager->sanbaoMove(Company::getCompanyId(), checkedProducts, moveType, moveCount);
}

void ProductService::updateProductData(){
    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message)
        QJsonArray productArr = data.value("products").toArray();
        DbHelper db;
        db.clearProduct();
        for(QJsonValue productobj:productArr){
            Product *product = new Product();
            product->loadFromJsonObject(productobj.toObject());
            db.insertProduct(*product);
        }
        emit this->sanbaoMoveSuccess();
    });

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(nullptr, "警告", message);
    });

    manager->getProductsByCompanyId(User::getCompanyId());
}

void ProductService::updateHistoryProduct(QWidget *widget, QList<HistoryProduct*> historyProducts, int type){
    if(historyProducts.size() == 0){
        QMessageBox::warning(widget, "警告", "无有效历史价格记录");
        return;
    }

    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        if(type == 0){
            QMessageBox::information(widget, "信息", message);
        }
    });

    manager->updateHistoryProducts(historyProducts, type);
}

void ProductService::getAllHistoryProdycts(
        QWidget *widget,
        UserRelation *relation,
        QList<DingdanDetail*> details){
    if(relation == nullptr){
        QMessageBox::warning(widget, "警告", "请选择客户或供应商！");
        return;
    }

    if(details.size() == 0){
        QMessageBox::warning(widget, "警告", "无有效商品条目！");
        return;
    }

    QString prodductIds;

    for(DingdanDetail *detail:details){
        prodductIds.append(detail->productId+"#");
    }

    int type = relation->type==1||relation->type==3?0:1;

    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message);
        QList<HistoryProduct*> historyProducts;
        for(QJsonValue objValue:data.value("allHistoryProducts").toArray()){
            HistoryProduct *historyProduct = new HistoryProduct();
            historyProduct->loadFromJsonObject(objValue.toObject());
            historyProducts.append(historyProduct);
        }

        emit this->getAllHistoryProdyctsSuccess(historyProducts);
    });

    manager->getAllHistoryProdycts(
                relation->sourceCompanyId,
                relation->targetCompanyId,
                prodductIds,
                type);
}

void ProductService::deleteProduct(QWidget *widget, Product *product){
    if(product == nullptr){
        QMessageBox::warning(widget, "警告", "删除商品不存在！");
        return;
    }

    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccess,
            [=](QString message)
    {
        QMessageBox::information(widget, "信息", message);
        widget->close();
    });

    manager->deleteProduct(product->companyId, product->productId);
}

void ProductService::getFormulaInfo(QWidget *widget, QString combineId){
    manager = new ProductNetworkAccessManager();

    connect(manager, &BaseNetworkAccessManager::onFailed,
            [=](QString message)
    {
        QMessageBox::warning(widget, "警告", message);
    });

    connect(manager, &BaseNetworkAccessManager::onSuccessWithData,
            [=](QString message, QJsonObject data)
    {
        Q_UNUSED(message)
        FormulaBase *formulaBase = new FormulaBase(data.value("formula").toObject());
        Formula *formula = new Formula();
        formula->formulaBase = formulaBase;
        Product *product = new Product(data.value("combineProduct").toObject());
        formula->setCombineProduct(product);
        QList<Product*> splitProducts;
        for(QJsonValue obj:data.value("splitProducts").toArray()){
            Product *product = new Product(obj.toObject());
            splitProducts.append(product);
        }
        formula->setSplitProducts(splitProducts);
        emit this->getFormulaInfoSuccess(formula);
    });

    manager->getFormulaInfo(Company::getCompanyId(), combineId);
}
